﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using KlubSportowy.Repositories;
using KlubSportowy.Models;
using System.Threading;

namespace KlubSportowy.Controllers
{
    public enum RepositorySize
    {
        Small,
        Medium,
        Large
    }

    public abstract class jTableController : Controller
    {

        protected readonly IjTableContainer _repository;

        #region Constructor

        protected jTableController(RepositorySize size = RepositorySize.Medium, string repositoryKey = "common")
        {
            _repository = RepositorySession.GetRepository(size, repositoryKey);
        }

        #endregion

        #region Student actions

        [HttpPost]
        public JsonResult ContributionsList(int jtStartIndex = 0, int jtPageSize = 0, string jtSorting = null)
        {
            
            try
            {
                Thread.Sleep(200);
                var contributionsCount = _repository.ContributionsRepository.GetContributionsCount();
                var contributions = _repository.ContributionsRepository.GetContributions(jtStartIndex, jtPageSize, jtSorting);
                
                return Json(new { Result = "OK", Records = contributions.Select( n => new {State = n.State, UserId = n.UserId, Amount = n.Amount,  AmountId = n.AmountId, COUId = n.COUId, PaymentDate = n.PaymentDate} ), TotalRecordCount = contributionsCount });
            }
            catch (Exception ex)
            {
                return Json(new { Result = "ERROR", Message = ex.Message });
            }
        }

        [HttpPost]
        public JsonResult ContributionsListByFiter(string name = "", int UserId = 0, int jtStartIndex = 0, int jtPageSize = 0, string jtSorting = null)
        {
            try
            {
                var studentCount = _repository.ContributionsRepository.GetContributionsCountByFilter(name, UserId);
                var students = _repository.ContributionsRepository.GetContributionsByFilter(name, UserId, jtStartIndex, jtPageSize, jtSorting);
                return Json(new { Result = "OK", Records = students, TotalRecordCount = studentCount });
            }
            catch (Exception ex)
            {
                return Json(new { Result = "ERROR", Message = ex.Message });
            }
        }

        [HttpPost]
        public JsonResult CreateContributions(UsersContributions contribution)
        {
            try
            {
                if (!ModelState.IsValid)
                {
                    return Json(new { Result = "ERROR", Message = "Form is not valid! Please correct it and try again." });
                }

                var addedContribution = _repository.ContributionsRepository.AddContribution(contribution);
                return Json(new { Result = "OK", Record = addedContribution });
            }
            catch (Exception ex)
            {
                return Json(new { Result = "ERROR", Message = ex.Message });
            }
        }

        [HttpPost]
        public JsonResult UpdateContribution(UsersContributions contribution)
        {
            try
            {
                //if (!ModelState.IsValid)
                //{
                //    return Json(new { Result = "ERROR", Message = "Form is not valid! Please correct it and try again." });
                //}

                _repository.ContributionsRepository.UpdateContribution(contribution);
                return Json(new { Result = "OK" });
            }
            catch (Exception ex)
            {
                return Json(new { Result = "ERROR", Message = ex.Message });
            }
        }

        [HttpPost]
        public JsonResult DeleteContribution(int COUId)
        {
            try
            {
                Thread.Sleep(50);
                _repository.ContributionsRepository.DeleteContribution(COUId);
                return Json(new { Result = "OK" });
            }
            catch (Exception ex)
            {
                return Json(new { Result = "ERROR", Message = ex.Message });
            }
        }

    #endregion

        #region Amount actions

        [HttpPost]
        public JsonResult GetAmountOptions()
        {
            try
            {
                var amounts = _repository.AmountRepository.GetAllAmount().Select(c => new { DisplayText = c.Description, Value = c.Id });
                return Json(new { Result = "OK", Options = amounts });
            }
            catch (Exception ex)
            {
                return Json(new { Result = "ERROR", Message = ex.Message });
            }
        }

        #endregion
        
        #region User actions

        [HttpPost]
        public JsonResult GetUserOptions()
        {
            try
            {
                var users = _repository.UserRepository.GetAllUsers().Select(c => new { DisplayText = c.UserName, Value = c.UserId});
                return Json(new { Result = "OK", Options = users });
            }
            catch (Exception ex)
            {
                return Json(new { Result = "ERROR", Message = ex.Message });
            }
        }

        #endregion
   }



    

    public static class RepositorySession
    {
        public static IjTableContainer GetRepository(RepositorySize size = RepositorySize.Medium, string repositoryKey = "common")
        {
            var sessionKey = "Repository_" + repositoryKey + "_" + size;

            if (HttpContext.Current.Session[sessionKey] == null)
            {
                HttpContext.Current.Session[sessionKey] = CreateRepository(size);
            }

            return HttpContext.Current.Session[sessionKey] as IjTableContainer;
        }

        private static IjTableContainer CreateRepository(RepositorySize size)
        {
            var Count = 8; //Default: Small
            switch (size)
            {
                case RepositorySize.Medium:
                    Count = 128;
                    break;
                case RepositorySize.Large:
                    Count = 1024;
                    break;
            }

            return new MemoryRepositoryContainer( new MemoryDataGenerator().Generate() );
        }

        public static Guid IntToGuid(int value)
        {
            byte[] bytes = new byte[16];
            BitConverter.GetBytes(value).CopyTo(bytes, 0);
            return new Guid(bytes);
        }
    }
}
